package nconv.convert;

import nconv.convert.WikiFormatUtils.FmtWikiI;
import nconv.utils.LogCenter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by lambert on 2016/4/7.
 */
public class WikiMarks{

	List<WikiFormatMark> marks = new ArrayList<>();

	public void addMark(WikiFormatMark newMark) { //TODO check if the mark can be added
		for (WikiFormatMark mark : marks) {
			if ((newMark.start >= mark.start && newMark.start < mark.end) ||
				(newMark.end > mark.start && newMark.end <= mark.end)) {
				if (!mark.type.accept(newMark.type)) {
					LogCenter.log("Reject adding mark: " + newMark + " due to conflict with existing mark: " + mark);
					return;
				}
			}
		}
		marks.add(newMark);
	}

	public int getLeftMaximumRemovableCharacters() {
		if (marks.size() == 0) {
			return Integer.MAX_VALUE;
		}
		int smallestLeft = Integer.MAX_VALUE;
		for (WikiFormatMark mark : marks) {
			if (mark.start == 0 && mark.end == 0)
				continue;
			smallestLeft = Math.min(mark.end, smallestLeft);
		}
		return smallestLeft - 1;
	}

	public List<WikiFormatMark> getWikiMarkList() {
		return marks;
	}

	public WikiFormatMark[] sort() {
		if (marks.size() > 0) {
			WikiFormatMark[] array = marks.toArray(new WikiFormatMark[0]);
			Arrays.sort(array, 0, marks.size());
			return array;
		} else {
			return new WikiFormatMark[0];
		}
	}

	public int size() {
		return marks.size();
	}

	public static enum WIKI_FORMAT_TYPE {
		NO_WIKI(0),
		HEADING(100),
		LIST_SYMBOL(200),
		LIST_LABEL(300),
		BOOK_MARK_SPAN(400),
		ITALIC(500),
		BOLD(600),
		HYPER_LINK(700),
		INTERNAL_LINK(800),
		TEMPLATE(900);

		//ATTR_FOT_TITLE(10000);

		private int value;
		private WIKI_FORMAT_TYPE(int value) {
			this.value = value;
		}

		public int getValue() {
			return value;
		}
	}

	public static class WikiFormatMark implements Comparable<WikiFormatMark>{
		FmtWikiI type;
		int start = Integer.MIN_VALUE;
		int end = Integer.MAX_VALUE;
		String content = null;

		public WikiFormatMark(FmtWikiI type) {
			this.type = type;
		}

		public WikiFormatMark(FmtWikiI type, String content) {
			this.type = type;
			this.content = content;
		}

		public WikiFormatMark(FmtWikiI type, String content, int start, int end) {
			this.type = type;
			this.content = content;
			this.start = start;
			this.end = end;
		}

		public String toString() {
			return "Type: " + type + ", content: " + content + ", start: " + start + ", end: " + end;
		}

		@Override
		public int compareTo(WikiFormatMark o) {
			if (type.compareTo(o.type) != 0) {
				return type.compareTo(o.type);
			} else 	if (start != o.start) {
				return start - o.start;
			} else if (end != o.end) {
				return o.end - end;
			} else {
				if (content == null && o.content == null) {
					return 0;
				} else if (content == null && o.content != null) {
					return -1;
				} else if (content != null && o.content == null) {
					return 1;
				} else {
					return content.compareTo(o.content);
				}
			}
		}
	}

}
